package dk.mga.androidExplore;

import java.util.ArrayList;
import java.util.Iterator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

public class SensorView extends View {
	protected int margin;
	protected ArrayList<Point> points;
	protected final String tag = "myLog";
	protected int backGroundColor = Color.LTGRAY;
	protected int width;
	protected int height;
	private final int IDLE = 0;
	private final int ANGLE_INPUT = 1;
	private final int XYMoving_INPUT = 2;
	private double angle;
	protected int mode=IDLE;

	
	public SensorView(Context context) {
		super(context);
		points = new ArrayList<Point>();
		Log.d(tag, "Construct SensorView and invalidate");
		invalidate();
	}

	public SensorView(Context context, int color) {
		this(context);
		backGroundColor = color;
		setBackgroundColor(backGroundColor);
	}
	
	Paint paint = new Paint();

	@Override
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawColor(backGroundColor);
		paint.setStrokeWidth(2);
		initDim();
		Log.d(tag, "onDraw() - width="+width+" height="+height+" points size="+points.size());
		if (mode == XYMoving_INPUT) {
			canvas.drawLine(2*margin, height-margin, 2*margin, margin, paint);// y akse
			canvas.drawLine(2*margin, height-margin, width-2*margin, height-margin, paint);// x akse
	        paint.setStrokeWidth(4);
			synchronized(points){
				Iterator<Point> i = points.iterator();
		        Point p;
		        int xOffset=0;
		        if (points.size()>0) { // First point defines where x=0
		        	xOffset = points.get(0).x - 2*margin;
		        }
		        while (i.hasNext()) {
		        	p = i.next();
		    		canvas.drawPoint((p.x-xOffset), p.y, paint);
		        }	        
			}
		}
		if (mode == ANGLE_INPUT) {
			paint.setStrokeWidth(4);
			float scaleRadius = height*0.3f;
	        // next 2 statement insert scale-marks indicating 0, 90, 180 and 270 degrees
			canvas.drawLine(width/2f-scaleRadius, height/2f, width/2f+scaleRadius, height/2f, paint);
			canvas.drawLine(width/2f, height/2f-scaleRadius, width/2f, height/2f+scaleRadius, paint);
	        canvas.drawCircle(width/2f, height/2f, height*0.27f, paint);
	        paint.setColor(Color.YELLOW);
	        canvas.drawCircle(width/2f, height/2f, height*0.25f, paint);
	        paint.setColor(Color.BLACK);
	        // Due to the increasing Y axis oriented downwards - PI is added to change the sign of the output
			canvas.drawLine(width/2f, height/2f, width/2f+height*0.25f*(float)Math.sin(angle+Math.PI), height/2f+height*0.25f*(float)Math.cos(angle+Math.PI), paint);
		}
	}
	
	
	public int getXresolution() {
		initDim();
		return width -3*margin;
	}

	private void initDim() {
		width = getWidth();
		height = getHeight();
		margin = width/20;
	}

	public int getYresolution() {
		initDim();
		return height-margin;
	}

	/**
	 * Helper class to store a set of coordinates for a  point
	 * @author allan
	 *
	 */
	public class Point {
		
		public Point(int x, int y) {
			this.x = x;
			this.y = -y;
		}
		int x;
		int y;
		@Override
		public String toString() {
			return "Point value x,y="+x+","+y;
		}
	}

	/**
	 * Method to set a new pair of coordinates.
	 * Notify the painter thread and let it paint
	 * them.
	 * @param x
	 * @param y
	 */
	public void setXYValues(int x, int y) {
		Point p;
		synchronized(points){
			if (points.size() > width/7) {
				p = points.remove(0);
				p.x = x;
				p.y = -y+(height-margin);
				points.add(p);
				Log.d(tag, "Filled up");
			} else {
				p = new Point(x, y);
				p.y += (height-margin);
				points.add(p);
			}
		}
		Log.d(tag, "setValue() "+ p.toString());
		mode = XYMoving_INPUT;
		invalidate();
	}
	
	public void setPoints(ArrayList<Point> listOfPoints) {
		points = listOfPoints;
		mode = XYMoving_INPUT;
		Log.d(tag, "setPoint called - points # "+listOfPoints.size());
		invalidate();
	}

	public void setAngles(double rad) {
		angle = rad;
		mode = ANGLE_INPUT;
		invalidate();
	}
}